using System;
using System.Threading;
using Styx;
using Styx.Combat.CombatRoutine;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using TreeSharp;

using Natfoth.Classes;
using Natfoth.Helpers;

namespace Natfoth
{
	class AkatoshCore : CombatRoutine
	{
        private Composite _combatBehavior;
        private Composite _combatBuffBehavior;
        private Composite _precombatBuffBehavior;
        private Composite _pullBehavior;
        private Composite _restBehavior;
        public bool _isCCLoaded;
	    public int CurrentSpec;

        public override sealed string Name { get { return GetName(); } }
	    public static string AuthorName = "Natfoth";
        public override WoWClass Class { get { return Me.Class; } }
        private static LocalPlayer Me { get { return ObjectManager.Me; } }
		public bool AoEMode;
        public static AkatoshCore Instance { get; private set; }

        public AkatoshCore()
        {
            Instance = this;

            // Register the events of the Stop / Start buttons in HB
            BotEvents.OnBotStarted += Lib.BotEvents_OnBotStarted;
            //BotEvents.OnBotStopped += BotEvents_OnBotStopped; Not used by Priest, look when at others

            string environment = Utils.IsBattleground ? "PVP" : "PVE";
            environment = ObjectManager.Me.IsInInstance ? "Instance" : environment;
            ConfigSettings.CurrentEnvironment = environment;

            LoadSettings(true);

            CurrentSpec = Talents.Spec;
        }

	    public override Composite CombatBehavior
        {
            get { if (_combatBehavior == null) { Lib.LogGreenMessage("Creating 'Combat' behavior"); _combatBehavior = CreateCombatBehavior(); } return _combatBehavior; }
        }

        public override Composite CombatBuffBehavior
        {
            get { if (_combatBuffBehavior == null) { Lib.LogGreenMessage("Creating 'CombatBuff' behavior"); _combatBuffBehavior = CreateCombatBuffBehavior(); } return _combatBuffBehavior; }
        }

        public override Composite PullBehavior
        {
            get { if (_pullBehavior == null) { Lib.LogGreenMessage("Creating 'Pull' behavior"); _pullBehavior = CreatePullBehavior(); } return _pullBehavior; }
        }

        public override Composite PreCombatBuffBehavior
        {
            get { if (_precombatBuffBehavior == null) { Lib.LogGreenMessage("Creating 'Buff' behavior"); _precombatBuffBehavior = CreateBuffBehavior(); } return _precombatBuffBehavior; }
        }

        public override Composite RestBehavior
        {
            get { if (_restBehavior == null) { Lib.LogGreenMessage("Creating 'Rest' behavior"); _restBehavior = CreateRestBehavior(); } return _restBehavior; }
        }

        public PrioritySelector CreateCombatBehavior()
        {
            return new PrioritySelector(

                new Decorator(ret => Class == WoWClass.Priest && CurrentSpec == 3, Priest.ShadowPriestCombat()),
                new Decorator(ret => Class == WoWClass.Priest && CurrentSpec == 1, Priest.DiscPriestCombat()),
                new Decorator(ret => Class == WoWClass.Shaman && CurrentSpec == 1, Shaman.ShamanElementalCombat()),
                new Decorator(ret => Class == WoWClass.Shaman && CurrentSpec == 2, Shaman.ShamanEnhancmentCombat()),
				new Decorator(ret => Class == WoWClass.Druid && CurrentSpec == 1, Druid.DruidMoonkinCombat())
            
             );

        }

        public PrioritySelector CreateCombatBuffBehavior()
        {
            return new PrioritySelector(
                new Decorator(ret => Class == WoWClass.Priest && CurrentSpec == 3, Priest.ShadowPriestCombatBuffs()),
                new Decorator(ret => Class == WoWClass.Priest && CurrentSpec == 1, Priest.DiscPriestCombatBuffs()),
                new Decorator(ret => Class == WoWClass.Shaman && CurrentSpec == 1, Shaman.ShamanElementalCombatBuffs()),
                new Decorator(ret => Class == WoWClass.Shaman && CurrentSpec == 2, Shaman.ShamanEnhancmentCombatBuffs()),
				new Decorator(ret => Class == WoWClass.Druid && CurrentSpec == 1, Druid.DruidCombatBuffs())
            );
        }

	    public override bool NeedPreCombatBuffs
	    {
            get 
            { 
                //if(Me.Class == WoWClass.Priest)
                //    return Priest.ShadowPriestNeedBuffs();

                return false; 
            }
	    }

        public override bool NeedRest 
        {
            get
            {
             //   if (Me.HealthPercent <= 40 || Me.ManaPercent <= 40)
            //        return true;

                return false;
            }
        }

        public PrioritySelector CreateRestBehavior()
        {
            return new PrioritySelector(
                new Decorator(ret => Class == WoWClass.Priest,  Priest.PriestRestBehavior()),
                new Decorator(ret => Class == WoWClass.Shaman, Shaman.ShamanRestBehavior()),
				new Decorator(ret => Class == WoWClass.Druid, Druid.DruidRestBehavior())
               
            );
        }

	    public PrioritySelector CreateBuffBehavior()
        {
            return new PrioritySelector(
                new Decorator(ret => Class == WoWClass.Priest && CurrentSpec == 3, Priest.ShadowPriestBuffs()),
                new Decorator(ret => Class == WoWClass.Priest && CurrentSpec == 1, Priest.DiscPriestBuffs()),
                new Decorator(ret => Class == WoWClass.Shaman && CurrentSpec == 1, Shaman.ShamanElementalBuffs()),
                new Decorator(ret => Class == WoWClass.Shaman && CurrentSpec == 2, Shaman.ShamanEnhancmentBuffs()),
				new Decorator(ret => Class == WoWClass.Druid && CurrentSpec == 1, Druid.DruidBuffs())
            );
        }

        public PrioritySelector CreatePullBehavior()
        {
            return new PrioritySelector(
                new Decorator(ret => Class == WoWClass.Priest && CurrentSpec == 3, Priest.ShadowPriestPullBehavior()),
                new Decorator(ret => Class == WoWClass.Priest && CurrentSpec == 1, Priest.DiscPriestPullBehavior()),
                new Decorator(ret => Class == WoWClass.Shaman && CurrentSpec == 1, Shaman.ShamanElementalPullBehavior()),
                new Decorator(ret => Class == WoWClass.Shaman && CurrentSpec == 2, Shaman.ShamanEnhancmentPullBehavior()),
				new Decorator(ret => Class == WoWClass.Druid && CurrentSpec == 1, Druid.DruidPullBehavior())
            );
        }


        #region Pulse
        public override void Pulse()
        {
            base.Pulse();

            if (Class == WoWClass.Priest && CurrentSpec == 3)
                Priest.ShadowPriestClassPulse();
            if (Class == WoWClass.Priest && CurrentSpec == 1)
                Priest.DiscPriestClassPulse();
            else if(Class == WoWClass.Shaman && CurrentSpec == 1)
                Shaman.ShamanElementalClassPulse();
            else if (Class == WoWClass.Shaman && CurrentSpec == 2)
                Shaman.ShamanEnchancmentClassPulse();
            else if (Class == WoWClass.Druid && CurrentSpec == 1)
                Druid.DruidClassPulse();
        }

        #endregion

        public string GetName()
        {
            if(Class == WoWClass.Priest)
                return String.Format("{0}({1}) by {2}", Priest.Name, Priest.Version, AuthorName);

            if (Class == WoWClass.Shaman)
                return String.Format("{0}({1}) by {2}", Shaman.Name, Shaman.Version, AuthorName);

			if (Class == WoWClass.Druid)
				return String.Format("{0}({1}) by {2}", Druid.Name, Druid.Version, AuthorName);

            return "Core None Found";
        }

        #region Load PriestSettings
        public void LoadSettings(bool silent)
        {
            if (!silent) Utils.Log("Loading settings ...");

            if (Class == WoWClass.Priest)
            {
                PriestSettings.Load();

                if (!silent)
                    Lib.LogGreenMessage(!_isCCLoaded
                                            ? "Settings loaded"
                                            : "Settings have been updated with your changes");
                PriestSettings.DirtyData = false;
            }
            else if(Class == WoWClass.Shaman)
            {
                ShamanSettings.Load();

                if (!silent)
                    Lib.LogGreenMessage(!_isCCLoaded
                                            ? "Settings loaded"
                                            : "Settings have been updated with your changes");
                ShamanSettings.DirtyData = false;
            }
            else if (Class == WoWClass.Druid)
            {
                DruidSettings.Load();

                if (!silent)
                    Lib.LogGreenMessage(!_isCCLoaded
                                            ? "Settings loaded"
                                            : "Settings have been updated with your changes");
                DruidSettings.DirtyData = false;
            }

        }
        #endregion

        #region Configuration Form Stuff
        // All very straight forward here. The name of the UI form is called UIForm
        private static Thread Thread { get; set; }

        private PriestForm _priestgui;
        private ShamanForm _shamangui;
        private DruidForm _druidgui;

        // This overrides HB OnButtonPress event. This where we assign the form to a thread and start the thread
        public override void OnButtonPress()
        {
            Thread = new Thread(OpenGui) { IsBackground = true, Name = "GuiThread" };
            Thread.Start();
        }
        public void OpenGui()
        {
            if (Class == WoWClass.Priest)
            {
                _priestgui = new PriestForm();
                _priestgui.ShowDialog();
            }

            if (Class == WoWClass.Shaman)
            {
                _shamangui = new ShamanForm();
                _shamangui.ShowDialog();
            }

            if (Class == WoWClass.Druid)
            {
                _druidgui = new DruidForm();
                _druidgui.ShowDialog();
            }
        }

        public override bool WantButton
        {
            get 
            { 
                if(Class == WoWClass.Priest)
                    return PriestSettings.ShowUI.Contains("always"); 
                if(Class == WoWClass.Shaman)
                    return ShamanSettings.ShowUI.Contains("always");
                if (Class == WoWClass.Druid)
                    return DruidSettings.ShowUI.Contains("always");

                return PriestSettings.ShowUI.Contains("always"); 
            }
        }
        #endregion
	}
}